#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
供应商管理系统模块
实现供应商评估、合同管理和绩效监控功能
"""

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import os
import json
from pathlib import Path

class SupplierManager:
    """供应商管理系统核心类"""
    
    def __init__(self, data_path='data/processed'):
        """
        初始化供应商管理系统
        
        参数:
            data_path: 数据文件路径
        """
        self.data_path = data_path
        self.suppliers_df = self._load_suppliers()
        self.contracts_df = self._load_or_create_contracts()
        self.performance_df = self._load_or_create_performance()
        
    def _load_suppliers(self):
        """加载供应商数据"""
        try:
            return pd.read_csv(os.path.join(self.data_path, 'suppliers.csv'))
        except FileNotFoundError:
            print(f"警告: 未找到供应商数据文件，将创建空数据框")
            return pd.DataFrame({
                'supplier_id': [],
                'name': [],
                'contact_person': [],
                'email': [],
                'phone': [],
                'address': [],
                'category': [],
                'registration_date': [],
                'qualification_status': [],
                'credit_score': []
            })
    
    def _load_or_create_contracts(self):
        """加载或创建合同数据"""
        contract_path = os.path.join(self.data_path, 'supplier_contracts.csv')
        try:
            return pd.read_csv(contract_path)
        except FileNotFoundError:
            print(f"信息: 未找到合同数据文件，将创建新文件")
            contracts_df = pd.DataFrame({
                'contract_id': [],
                'supplier_id': [],
                'start_date': [],
                'end_date': [],
                'contract_type': [],
                'payment_terms': [],
                'contract_value': [],
                'currency': [],
                'status': [],
                'renewal_reminder_sent': []
            })
            contracts_df.to_csv(contract_path, index=False)
            return contracts_df
    
    def _load_or_create_performance(self):
        """加载或创建绩效数据"""
        performance_path = os.path.join(self.data_path, 'supplier_performance.csv')
        try:
            return pd.read_csv(performance_path)
        except FileNotFoundError:
            print(f"信息: 未找到绩效数据文件，将创建新文件")
            performance_df = pd.DataFrame({
                'evaluation_id': [],
                'supplier_id': [],
                'evaluation_date': [],
                'quality_score': [],
                'delivery_score': [],
                'cost_score': [],
                'service_score': [],
                'overall_score': [],
                'evaluator': [],
                'comments': []
            })
            performance_df.to_csv(performance_path, index=False)
            return performance_df
    
    def register_supplier(self, supplier_data):
        """
        注册新供应商
        
        参数:
            supplier_data: 包含供应商信息的字典
        
        返回:
            新供应商ID
        """
        # 验证必要字段
        required_fields = ['name', 'contact_person', 'email', 'phone', 'category']
        for field in required_fields:
            if field not in supplier_data:
                raise ValueError(f"缺少必要字段: {field}")
        
        # 生成新的供应商ID
        if len(self.suppliers_df) == 0:
            new_id = "SUP10001"
        else:
            last_id = self.suppliers_df['supplier_id'].iloc[-1]
            new_id = f"SUP{int(last_id[3:]) + 1}"
        
        # 添加默认值
        supplier_data['supplier_id'] = new_id
        supplier_data['registration_date'] = supplier_data.get('registration_date', datetime.now().strftime('%Y-%m-%d'))
        supplier_data['qualification_status'] = supplier_data.get('qualification_status', '待审核')
        supplier_data['credit_score'] = supplier_data.get('credit_score', 0)
        
        # 添加到数据框
        self.suppliers_df = pd.concat([
            self.suppliers_df, 
            pd.DataFrame([supplier_data])
        ], ignore_index=True)
        
        # 保存数据
        self.suppliers_df.to_csv(os.path.join(self.data_path, 'suppliers.csv'), index=False)
        
        return new_id
    
    def update_supplier(self, supplier_id, update_data):
        """
        更新供应商信息
        
        参数:
            supplier_id: 供应商ID
            update_data: 要更新的数据字典
        
        返回:
            更新是否成功
        """
        if supplier_id not in self.suppliers_df['supplier_id'].values:
            return False
        
        # 更新数据
        for key, value in update_data.items():
            if key in self.suppliers_df.columns and key != 'supplier_id':
                self.suppliers_df.loc[self.suppliers_df['supplier_id'] == supplier_id, key] = value
        
        # 保存数据
        self.suppliers_df.to_csv(os.path.join(self.data_path, 'suppliers.csv'), index=False)
        
        return True
    
    def get_supplier(self, supplier_id):
        """
        获取供应商信息
        
        参数:
            supplier_id: 供应商ID
        
        返回:
            供应商信息字典
        """
        if supplier_id not in self.suppliers_df['supplier_id'].values:
            return None
        
        supplier_data = self.suppliers_df[self.suppliers_df['supplier_id'] == supplier_id].iloc[0].to_dict()
        return supplier_data
    
    def list_suppliers(self, filters=None):
        """
        列出供应商
        
        参数:
            filters: 过滤条件字典
        
        返回:
            供应商列表
        """
        result_df = self.suppliers_df.copy()
        
        if filters:
            for key, value in filters.items():
                if key in result_df.columns:
                    result_df = result_df[result_df[key] == value]
        
        return result_df.to_dict('records')
    
    def add_contract(self, contract_data):
        """
        添加供应商合同
        
        参数:
            contract_data: 合同数据字典
        
        返回:
            合同ID
        """
        # 验证必要字段
        required_fields = ['supplier_id', 'start_date', 'end_date', 'contract_type', 'payment_terms']
        for field in required_fields:
            if field not in contract_data:
                raise ValueError(f"缺少必要字段: {field}")
        
        # 验证供应商是否存在
        if contract_data['supplier_id'] not in self.suppliers_df['supplier_id'].values:
            raise ValueError(f"供应商不存在: {contract_data['supplier_id']}")
        
        # 生成新的合同ID
        if len(self.contracts_df) == 0:
            new_id = "CON10001"
        else:
            last_id = self.contracts_df['contract_id'].iloc[-1]
            new_id = f"CON{int(last_id[3:]) + 1}"
        
        # 添加默认值
        contract_data['contract_id'] = new_id
        contract_data['status'] = contract_data.get('status', '有效')
        contract_data['renewal_reminder_sent'] = contract_data.get('renewal_reminder_sent', False)
        
        # 添加到数据框
        self.contracts_df = pd.concat([
            self.contracts_df, 
            pd.DataFrame([contract_data])
        ], ignore_index=True)
        
        # 保存数据
        self.contracts_df.to_csv(os.path.join(self.data_path, 'supplier_contracts.csv'), index=False)
        
        return new_id
    
    def update_contract(self, contract_id, update_data):
        """
        更新合同信息
        
        参数:
            contract_id: 合同ID
            update_data: 要更新的数据字典
        
        返回:
            更新是否成功
        """
        if contract_id not in self.contracts_df['contract_id'].values:
            return False
        
        # 更新数据
        for key, value in update_data.items():
            if key in self.contracts_df.columns and key != 'contract_id':
                self.contracts_df.loc[self.contracts_df['contract_id'] == contract_id, key] = value
        
        # 保存数据
        self.contracts_df.to_csv(os.path.join(self.data_path, 'supplier_contracts.csv'), index=False)
        
        return True
    
    def get_contract(self, contract_id):
        """
        获取合同信息
        
        参数:
            contract_id: 合同ID
        
        返回:
            合同信息字典
        """
        if contract_id not in self.contracts_df['contract_id'].values:
            return None
        
        contract_data = self.contracts_df[self.contracts_df['contract_id'] == contract_id].iloc[0].to_dict()
        return contract_data
    
    def list_contracts(self, supplier_id=None, status=None):
        """
        列出合同
        
        参数:
            supplier_id: 供应商ID
            status: 合同状态
        
        返回:
            合同列表
        """
        result_df = self.contracts_df.copy()
        
        if supplier_id:
            result_df = result_df[result_df['supplier_id'] == supplier_id]
        
        if status:
            result_df = result_df[result_df['status'] == status]
        
        return result_df.to_dict('records')
    
    def check_expiring_contracts(self, days_threshold=30):
        """
        检查即将到期的合同
        
        参数:
            days_threshold: 到期天数阈值
        
        返回:
            即将到期的合同列表
        """
        today = datetime.now().date()
        expiry_date = today + timedelta(days=days_threshold)
        
        # 转换日期字符串为日期对象
        self.contracts_df['end_date'] = pd.to_datetime(self.contracts_df['end_date']).dt.date
        
        # 筛选即将到期且状态为有效的合同
        expiring_contracts = self.contracts_df[
            (self.contracts_df['end_date'] <= expiry_date) & 
            (self.contracts_df['end_date'] >= today) & 
            (self.contracts_df['status'] == '有效')
        ]
        
        # 转换回字符串格式以便序列化
        expiring_contracts['end_date'] = expiring_contracts['end_date'].astype(str)
        self.contracts_df['end_date'] = self.contracts_df['end_date'].astype(str)
        
        return expiring_contracts.to_dict('records')
    
    def add_performance_evaluation(self, evaluation_data):
        """
        添加供应商绩效评估
        
        参数:
            evaluation_data: 评估数据字典
        
        返回:
            评估ID
        """
        # 验证必要字段
        required_fields = ['supplier_id', 'quality_score', 'delivery_score', 'cost_score', 'service_score', 'evaluator']
        for field in required_fields:
            if field not in evaluation_data:
                raise ValueError(f"缺少必要字段: {field}")
        
        # 验证供应商是否存在
        if evaluation_data['supplier_id'] not in self.suppliers_df['supplier_id'].values:
            raise ValueError(f"供应商不存在: {evaluation_data['supplier_id']}")
        
        # 生成新的评估ID
        if len(self.performance_df) == 0:
            new_id = "EVA10001"
        else:
            last_id = self.performance_df['evaluation_id'].iloc[-1]
            new_id = f"EVA{int(last_id[3:]) + 1}"
        
        # 计算总体评分
        scores = [
            evaluation_data['quality_score'],
            evaluation_data['delivery_score'],
            evaluation_data['cost_score'],
            evaluation_data['service_score']
        ]
        overall_score = sum(scores) / len(scores)
        
        # 添加默认值
        evaluation_data['evaluation_id'] = new_id
        evaluation_data['evaluation_date'] = evaluation_data.get('evaluation_date', datetime.now().strftime('%Y-%m-%d'))
        evaluation_data['overall_score'] = round(overall_score, 2)
        evaluation_data['comments'] = evaluation_data.get('comments', '')
        
        # 添加到数据框
        self.performance_df = pd.concat([
            self.performance_df, 
            pd.DataFrame([evaluation_data])
        ], ignore_index=True)
        
        # 保存数据
        self.performance_df.to_csv(os.path.join(self.data_path, 'supplier_performance.csv'), index=False)
        
        # 更新供应商的信用评分
        self._update_supplier_credit_score(evaluation_data['supplier_id'])
        
        return new_id
    
    def _update_supplier_credit_score(self, supplier_id):
        """
        更新供应商信用评分
        
        参数:
            supplier_id: 供应商ID
        """
        # 获取该供应商的所有评估
        supplier_evaluations = self.performance_df[self.performance_df['supplier_id'] == supplier_id]
        
        if len(supplier_evaluations) == 0:
            return
        
        # 计算平均评分，近期评分权重更高
        supplier_evaluations = supplier_evaluations.sort_values('evaluation_date')
        recent_weight = 0.7
        history_weight = 0.3
        
        if len(supplier_evaluations) == 1:
            avg_score = supplier_evaluations['overall_score'].iloc[0]
        else:
            recent_score = supplier_evaluations['overall_score'].iloc[-1]
            history_scores = supplier_evaluations['overall_score'].iloc[:-1].mean()
            avg_score = recent_score * recent_weight + history_scores * history_weight
        
        # 更新供应商信用评分 (0-100)
        credit_score = int(avg_score * 20)  # 假设评分是0-5分制
        self.update_supplier(supplier_id, {'credit_score': credit_score})
    
    def get_supplier_performance(self, supplier_id):
        """
        获取供应商绩效历史
        
        参数:
            supplier_id: 供应商ID
        
        返回:
            绩效评估列表
        """
        if supplier_id not in self.suppliers_df['supplier_id'].values:
            return []
        
        supplier_evaluations = self.performance_df[self.performance_df['supplier_id'] == supplier_id]
        return supplier_evaluations.to_dict('records')
    
    def get_performance_trends(self, supplier_id, metric=None):
        """
        获取供应商绩效趋势
        
        参数:
            supplier_id: 供应商ID
            metric: 指标名称 (quality_score, delivery_score, cost_score, service_score, overall_score)
        
        返回:
            绩效趋势数据
        """
        if supplier_id not in self.suppliers_df['supplier_id'].values:
            return {}
        
        supplier_evaluations = self.performance_df[self.performance_df['supplier_id'] == supplier_id].copy()
        
        if len(supplier_evaluations) == 0:
            return {}
        
        # 确保日期格式正确
        supplier_evaluations['evaluation_date'] = pd.to_datetime(supplier_evaluations['evaluation_date'])
        supplier_evaluations = supplier_evaluations.sort_values('evaluation_date')
        
        # 准备趋势数据
        trend_data = {
            'dates': supplier_evaluations['evaluation_date'].dt.strftime('%Y-%m-%d').tolist()
        }
        
        metrics = ['quality_score', 'delivery_score', 'cost_score', 'service_score', 'overall_score']
        if metric and metric in metrics:
            metrics = [metric]
        
        for m in metrics:
            trend_data[m] = supplier_evaluations[m].tolist()
        
        return trend_data
    
    def get_top_suppliers(self, category=None, limit=10):
        """
        获取表现最好的供应商
        
        参数:
            category: 供应商类别
            limit: 返回数量限制
        
        返回:
            供应商列表
        """
        suppliers = self.suppliers_df.copy()
        
        if category:
            suppliers = suppliers[suppliers['category'] == category]
        
        # 按信用评分排序
        top_suppliers = suppliers.sort_values('credit_score', ascending=False).head(limit)
        return top_suppliers.to_dict('records')
    
    def export_supplier_directory(self, output_path=None):
        """
        导出供应商目录
        
        参数:
            output_path: 输出路径
        
        返回:
            导出文件路径
        """
        if output_path is None:
            output_dir = Path('reports')
            output_dir.mkdir(exist_ok=True)
            output_path = output_dir / 'supplier_directory.json'
        
        # 准备导出数据
        export_data = []
        for _, supplier in self.suppliers_df.iterrows():
            supplier_id = supplier['supplier_id']
            supplier_data = supplier.to_dict()
            
            # 添加合同信息
            contracts = self.list_contracts(supplier_id=supplier_id)
            active_contracts = [c for c in contracts if c['status'] == '有效']
            supplier_data['active_contracts'] = len(active_contracts)
            
            # 添加绩效信息
            performance = self.get_supplier_performance(supplier_id)
            if performance:
                recent_performance = sorted(performance, key=lambda x: x['evaluation_date'], reverse=True)[0]
                supplier_data['recent_performance'] = recent_performance['overall_score']
            else:
                supplier_data['recent_performance'] = None
            
            export_data.append(supplier_data)
        
        # 导出为JSON
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(export_data, f, ensure_ascii=False, indent=2)
        
        return str(output_path)


# 如果直接运行此脚本
if __name__ == "__main__":
    # 创建供应商管理实例
    sm = SupplierManager()
    
    # 示例：注册新供应商
    new_supplier = {
        'name': '优质电子元件有限公司',
        'contact_person': '张经理',
        'email': 'zhang@example.com',
        'phone': '13800138000',
        'address': '深圳市南山区科技园',
        'category': '电子元件'
    }
    
    supplier_id = sm.register_supplier(new_supplier)
    print(f"已注册新供应商，ID: {supplier_id}")
    
    # 示例：添加合同
    contract = {
        'supplier_id': supplier_id,
        'start_date': '2025-01-01',
        'end_date': '2025-12-31',
        'contract_type': '年度采购合同',
        'payment_terms': '月结30天',
        'contract_value': 1000000,
        'currency': 'CNY'
    }
    
    contract_id = sm.add_contract(contract)
    print(f"已添加新合同，ID: {contract_id}")
    
    # 示例：添加绩效评估
    evaluation = {
        'supplier_id': supplier_id,
        'quality_score': 4.5,
        'delivery_score': 4.2,
        'cost_score': 3.8,
        'service_score': 4.0,
        'evaluator': '李采购'
    }
    
    evaluation_id = sm.add_performance_evaluation(evaluation)
    print(f"已添加绩效评估，ID: {evaluation_id}")
    
    # 示例：检查即将到期的合同
    expiring = sm.check_expiring_contracts(days_threshold=365)
    print(f"发现 {len(expiring)} 个即将在一年内到期的合同")